package cn.tedu.sgos.user.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;

import cn.tedu.sgos.base.exception.CaptchaException;
import cn.tedu.sgos.base.exception.ServiceException;
import cn.tedu.sgos.base.response.StatusCode;
import cn.tedu.sgos.user.mapper.UserMapper;
import cn.tedu.sgos.user.pojo.dto.UserLoginParam;
import cn.tedu.sgos.user.pojo.dto.UserSaveParam;
import cn.tedu.sgos.user.pojo.entity.User;
import cn.tedu.sgos.user.pojo.vo.UserVO;
import cn.tedu.sgos.user.service.UserService;
import cn.tedu.sgos.utils.CacheUtil;
import cn.tedu.sgos.utils.SMSUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.Serializable;
import java.util.Date;


/**
 * @Author: Miyako
 * @Date: 2024-08-30-17:13
 * @Description:
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    CacheUtil cacheUtil;



    @Autowired
    SMSUtil smsUtil;

    @Autowired
    UserMapper userMapper;


    @Override
    public UserVO login(UserLoginParam userLoginParam) {
        String code = userLoginParam.getCode();
        //redis里查找验证码
        Serializable Captcha = cacheUtil.get("code");
        //判断验证码是否过期
        if (Captcha == null) {
            throw new CaptchaException(StatusCode.DATA_UNEXISTS);
        }
        //判断验证码是否正确，不区分大小写
        if (code.equalsIgnoreCase(String.valueOf(Captcha))) {
            String username = userLoginParam.getPhone();
            String password = userLoginParam.getPassword();
            log.debug("验证中...");
            UserVO userVO = userMapper.selectByPhone(username);
            if (userVO == null) {
                log.debug("查无此人");
                throw new ServiceException(StatusCode.USERNAME_ERROR);
            }
            if (!userVO.getPassword().equals(password)) {
                log.debug("密码错误");
                throw new ServiceException(StatusCode.PASSWORD_ERROR);
            }
            return userVO;
        } else {
            log.debug("验证码错误");
            throw new CaptchaException(StatusCode.VALIDATE_ERROR);
        }
    }

    @Override
    public String getCaptcha() {
        //生成验证码图片，参数为 长宽,验证码数量,干扰线条数
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(100, 50, 4, 50);
        //获取验证码值
        String code = captcha.getCode();
        log.debug("验证码限时30s" + code);
        //设置30s限时的验证码存入redis
        cacheUtil.setExpire("code", (Serializable) code, 30L);
        log.debug("已存入");
        //获取用Base64编码的图片JSON字符串
        String data = captcha.getImageBase64Data();
        return data;
    }

    @Override
    public void sendSMS(String phone) {
        //检测验证码是否过期
        Serializable serializable = cacheUtil.get(phone);
        if (serializable != null) {
            throw new RuntimeException("验证码还未过期,不要重复发送");
        }
        //发送短信,接收验证码
        String authCode = smsUtil.generateSMS(phone);

        //设置60s限时将短信验证码存入Redis
        cacheUtil.setExpire(phone, authCode, 60L);
        log.debug("已存入");

    }

    @Override
    public UserVO checkSMS(String phone, String auCode) {
        //获取redis中手机号对应的验证码
        Serializable authCode = cacheUtil.get(phone);
        //判断是否过期
        if (authCode == null) {
            log.debug("验证码过期或未发送");
            throw new RuntimeException("验证码不存在");
        }
        //判断验证码是否正确
        if (auCode.equalsIgnoreCase((String) authCode)) {
            log.debug("校验通过");
            return userMapper.selectByPhone(phone);
            //TOD使用手机号去查询用户信息返回给前端
        } else {
            log.debug("验证失败");
            throw new RuntimeException("验证码错误");
        }

    }

    @Override
    public void saveUser(@RequestBody UserSaveParam save) {
        //校验短信验证码
       checkSMS(save.getPhone(),save.getAuCode());
        User user = new User();
        BeanUtils.copyProperties(save, user);
        UserVO userVO = userMapper.selectByPhone(user.getPhone());
        log.debug("查询{}",userVO);
        //检查重命名
        if (userVO == null) {
            //添加用户
            user.setCreateTime(new Date());
            //随机生成一个昵称
            RandomGenerator randomGenerator = new RandomGenerator("0123456789",12);
            user.setNickname("用户_"+randomGenerator.generate());
            userMapper.insert(user);
        }else {
            throw new RuntimeException("重名");
        }

    }


    /*
     * @param: [saveParam]
     * @return: void
     * @description: 修改密码和找回（重置）密码两个功能
     **/
    @Override
    public void changePwd(UserSaveParam saveParam) {
        String phone = saveParam.getPhone();
        String auCode = saveParam.getAuCode();
        UserVO userVO = userMapper.selectByPhone(phone);
        //检查用户是否存在
        if (userVO != null){
            //校验短信验证码
            checkSMS(phone, auCode);
            //正确->修改密码
            User user = new User();
            user.setId(userVO.getId());
            user.setUpdateTime(new Date());
            user.setPassword(saveParam.getPassword());
            userMapper.update(user);
        }
    }


}
